package com.loong.shop.business;

import com.loong.common.executor.AsyncExecutor;
import com.loong.common.mybatis.business.AbstractBusiness;
import com.loong.common.rabbitmq.dto.base.RepositoryEventDto;
import com.loong.common.rabbitmq.enums.RepositoryEvent;
import com.loong.common.utils.TransformUtils;
import com.loong.shop.common.backend.param.GoodsSizeValueQueryParam;
import com.loong.shop.common.backend.param.GoodsSpecificationReportParam;
import com.loong.shop.model.GoodsSpecificationName;
import com.loong.shop.model.GoodsSpecificationValue;
import com.loong.shop.mq.GoodsSpecificationReport;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Description:
 * @Author: 刘群
 * @Date: 2020/10/27 7:49
 */
@Repository
public class GoodsSpecificationValueBusiness extends AbstractBusiness<GoodsSpecificationValue> {

    @Resource
    private AsyncExecutor asyncExecutor;

    @Resource
    private GoodsSpecificationReport goodsSpecificationReport;

    @Resource
    private GoodsSpecificationNameBusiness goodsSpecificationNameBusiness;

    /**
     * 根据参数查询商品规格值
     *
     * @param sizeNameId 商品规格名称id
     * @param sizeValue  商品规格值
     * @return 商品规格值集合
     */
    public List<GoodsSpecificationValue> findSizeValueByParam(Long sizeNameId, String sizeValue) {
        Condition condition = new Condition(GoodsSpecificationValue.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("goodsSpecificationId", sizeNameId);
        if (ObjectUtils.isNotEmpty(sizeValue)) {
            criteria.andLike("goodsSpecificationValue", "%" + sizeValue + "%");
        }
        return findByCondition(condition);
    }

    /**
     * 根据参数查询是否存在重复的规格值
     *
     * @param param 查询参数：商品规格名称id、商品规格值
     * @return 商品规格值集合
     */
    public List<GoodsSpecificationValue> findDuplicationValueByParam(GoodsSizeValueQueryParam param) {
        Condition condition = new Condition(GoodsSpecificationValue.class);
        Example.Criteria criteria = condition.createCriteria();
        criteria.andEqualTo("goodsSpecificationId", param.getSizeNameId());
        criteria.andEqualTo("goodsSpecificationValue", param.getSizeValue());
        return findByCondition(condition);
    }

    @Override
    public void save(GoodsSpecificationValue model) {
        super.save(model);
        asyncExecutor.async(()->{
            GoodsSpecificationReportParam param = buildParam(model);
            report(param,RepositoryEvent.CREATE);
        });
    }

    private GoodsSpecificationReportParam buildParam(GoodsSpecificationValue model){
        Long goodsSpecificationId = model.getGoodsSpecificationId();
        GoodsSpecificationName nameModel = goodsSpecificationNameBusiness.findById(goodsSpecificationId);
        GoodsSpecificationReportParam param = TransformUtils.transform(model, GoodsSpecificationReportParam.class);
        param.setGoodsSpecificationName(nameModel.getName());
        param.setGoodsSpecificationId(nameModel.getId());
        param.setShopId(nameModel.getShopId());
        return param;
    }

    @Override
    public void deleteByIds(String ids) {
        super.deleteByIds(ids);
        asyncExecutor.async(()->{
            GoodsSpecificationReportParam param = GoodsSpecificationReportParam.builder().ids(ids).build();
            report(param,RepositoryEvent.DELETE);
        });
    }

    @Override
    public void updateByPrimaryKeySelective(GoodsSpecificationValue model) {
        GoodsSpecificationValue dbModel = super.findById(model.getId());
        super.updateByPrimaryKeySelective(model);
        asyncExecutor.async(()->{
            GoodsSpecificationReportParam param;
            if(dbModel.getGoodsSpecificationId().equals(model.getGoodsSpecificationId())){
                param = TransformUtils.transform(model, GoodsSpecificationReportParam.class);
            }else {
                param = buildParam(model);
            }
            report(param,RepositoryEvent.UPDATE);
        });
    }
    private void report(GoodsSpecificationReportParam param, RepositoryEvent event){
        RepositoryEventDto<GoodsSpecificationReportParam> goodsCategoryRepositoryEventDto =
                RepositoryEventDto.buildWithCreate(null);
        switch (event.getCode()){
            case 1:
                goodsCategoryRepositoryEventDto= RepositoryEventDto.buildWithCreate(param);
                break;
            case 2:
                 goodsCategoryRepositoryEventDto = RepositoryEventDto.buildWithUpdate(param);
                break;
            case 3:
                goodsCategoryRepositoryEventDto = RepositoryEventDto.buildWithDelete(param);
                break;
        }
        goodsSpecificationReport.report(goodsCategoryRepositoryEventDto);
    }
}
